package com.kkkkkba.search.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.gson.Gson;
import com.kkkkkba.search.common.ErrorCode;
import com.kkkkkba.search.constant.CommonConstant;
import com.kkkkkba.search.exception.BusinessException;
import com.kkkkkba.search.exception.ThrowUtils;
import com.kkkkkba.search.mapper.CodeMapper;
import com.kkkkkba.search.model.dto.code.CodeQueryRequest;
import com.kkkkkba.search.model.entity.Code;
import com.kkkkkba.search.model.entity.User;
import com.kkkkkba.search.model.vo.CodeVO;
import com.kkkkkba.search.model.vo.UserVO;
import com.kkkkkba.search.service.CodeService;
import com.kkkkkba.search.service.UserService;
import com.kkkkkba.search.utils.SqlUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 帖子服务实现
 *
 */
@Service
@Slf4j
public class CodeServiceImpl extends ServiceImpl<CodeMapper, Code> implements CodeService {

    private final static Gson GSON = new Gson();

    @Resource
    private UserService userService;

//    @Resource
//    private CodeThumbMapper codeThumbMapper;
//
//    @Resource
//    private CodeFavourMapper codeFavourMapper;

//    @Resource
//    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Override
    public void validCode(Code code, boolean add) {
        if (code == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String title = code.getTitle();
        String content = code.getContent();
        String tags = code.getTags();
        // 创建时，参数不能为空
        if (add) {
            ThrowUtils.throwIf(StringUtils.isAnyBlank(title, content, tags), ErrorCode.PARAMS_ERROR);
        }
        // 有参数则校验
        if (StringUtils.isNotBlank(title) && title.length() > 80) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "标题过长");
        }
        if (StringUtils.isNotBlank(content) && content.length() > 8192) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "内容过长");
        }
    }

    /**
     * 获取查询包装类
     *
     * @param codeQueryRequest
     * @return
     */
    @Override
    public QueryWrapper<Code> getQueryWrapper(CodeQueryRequest codeQueryRequest) {
        QueryWrapper<Code> queryWrapper = new QueryWrapper<>();
        if (codeQueryRequest == null) {
            return queryWrapper;
        }
        String searchText = codeQueryRequest.getSearchText();
        String sortField = codeQueryRequest.getSortField();
        String sortOrder = codeQueryRequest.getSortOrder();
        Long id = codeQueryRequest.getId();
        String title = codeQueryRequest.getTitle();
        String content = codeQueryRequest.getContent();
        List<String> tagList = codeQueryRequest.getTags();
            Long userId = codeQueryRequest.getUserId();
        Long notId = codeQueryRequest.getNotId();
        // 拼接查询条件
        if (StringUtils.isNotBlank(searchText)) {
            queryWrapper.like("title", searchText).or().like("content", searchText);
        }
        queryWrapper.like(StringUtils.isNotBlank(title), "title", title);
        queryWrapper.like(StringUtils.isNotBlank(content), "content", content);
        if (CollectionUtils.isNotEmpty(tagList)) {
            for (String tag : tagList) {
                queryWrapper.like("tags", "\"" + tag + "\"");
            }
        }
        queryWrapper.ne(ObjectUtils.isNotEmpty(notId), "id", notId);
        queryWrapper.eq(ObjectUtils.isNotEmpty(id), "id", id);
        queryWrapper.eq(ObjectUtils.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq("isDelete", false);
        queryWrapper.orderBy(SqlUtils.validSortField(sortField), sortOrder.equals(CommonConstant.SORT_ORDER_ASC),
                sortField);
        return queryWrapper;
    }


    @Override
    public CodeVO getCodeVO(Code code, HttpServletRequest request) {
        CodeVO codeVO = CodeVO.objToVo(code);
        long codeId = code.getId();
        // 1. 关联查询用户信息
        Long userId = code.getUserId();
        User user = null;
        if (userId != null && userId > 0) {
            user = userService.getById(userId);
        }
        UserVO userVO = userService.getUserVO(user);
        codeVO.setUser(userVO);
        // 2. 已登录，获取用户点赞、收藏状态
        User loginUser = userService.getLoginUserPermitNull(request);
//        if (loginUser != null) {
//            // 获取点赞
//            QueryWrapper<CodeThumb> codeThumbQueryWrapper = new QueryWrapper<>();
//            codeThumbQueryWrapper.in("codeId", codeId);
//            codeThumbQueryWrapper.eq("userId", loginUser.getId());
//            CodeThumb codeThumb = codeThumbMapper.selectOne(codeThumbQueryWrapper);
//            codeVO.setHasThumb(codeThumb != null);
//            // 获取收藏
//            QueryWrapper<CodeFavour> codeFavourQueryWrapper = new QueryWrapper<>();
//            codeFavourQueryWrapper.in("codeId", codeId);
//            codeFavourQueryWrapper.eq("userId", loginUser.getId());
//            CodeFavour codeFavour = codeFavourMapper.selectOne(codeFavourQueryWrapper);
//            codeVO.setHasFavour(codeFavour != null);
//        }
        return codeVO;
    }

    @Override
    public Page<CodeVO> getCodeVOPage(Page<Code> codePage, HttpServletRequest request) {
        List<Code> codeList = codePage.getRecords();
        Page<CodeVO> codeVOPage = new Page<>(codePage.getCurrent(), codePage.getSize(), codePage.getTotal());
        if (CollectionUtils.isEmpty(codeList)) {
            return codeVOPage;
        }
        // 1. 关联查询用户信息
        Set<Long> userIdSet = codeList.stream().map(Code::getUserId).collect(Collectors.toSet());
        Map<Long, List<User>> userIdUserListMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        // 2. 已登录，获取用户点赞、收藏状态
        Map<Long, Boolean> codeIdHasThumbMap = new HashMap<>();
        Map<Long, Boolean> codeIdHasFavourMap = new HashMap<>();
//        User loginUser = userService.getLoginUserPermitNull(request);
//        if (loginUser != null) {
//            Set<Long> codeIdSet = codeList.stream().map(Code::getId).collect(Collectors.toSet());
//            loginUser = userService.getLoginUser(request);
//            // 获取点赞
//            QueryWrapper<CodeThumb> codeThumbQueryWrapper = new QueryWrapper<>();
//            codeThumbQueryWrapper.in("codeId", codeIdSet);
//            codeThumbQueryWrapper.eq("userId", loginUser.getId());
//            List<CodeThumb> codeCodeThumbList = codeThumbMapper.selectList(codeThumbQueryWrapper);
//            codeCodeThumbList.forEach(codeCodeThumb -> codeIdHasThumbMap.put(codeCodeThumb.getCodeId(), true));
//            // 获取收藏
//            QueryWrapper<CodeFavour> codeFavourQueryWrapper = new QueryWrapper<>();
//            codeFavourQueryWrapper.in("codeId", codeIdSet);
//            codeFavourQueryWrapper.eq("userId", loginUser.getId());
//            List<CodeFavour> codeFavourList = codeFavourMapper.selectList(codeFavourQueryWrapper);
//            codeFavourList.forEach(codeFavour -> codeIdHasFavourMap.put(codeFavour.getCodeId(), true));
//        }
        // 填充信息
        List<CodeVO> codeVOList = codeList.stream().map(code -> {
            CodeVO codeVO = CodeVO.objToVo(code);
            Long userId = code.getUserId();
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            codeVO.setUser(userService.getUserVO(user));
            codeVO.setHasThumb(codeIdHasThumbMap.getOrDefault(code.getId(), false));
            codeVO.setHasFavour(codeIdHasFavourMap.getOrDefault(code.getId(), false));
            return codeVO;
        }).collect(Collectors.toList());
        codeVOPage.setRecords(codeVOList);
        return codeVOPage;
    }

    @Override
    public Page<CodeVO> listCodeVOByPage(CodeQueryRequest codeQueryRequest, HttpServletRequest request) {
        long current = codeQueryRequest.getCurrent();
        long size = codeQueryRequest.getPageSize();
        QueryWrapper<Code> queryWrapper = this.getQueryWrapper(codeQueryRequest);
        Page<Code> codePage = this.page(new Page<>(current, size),
                queryWrapper);
        return this.getCodeVOPage(codePage,request);
    }

}




